package com.ruoyi.ams.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;

import com.ruoyi.ams.domain.AmsAssetRequisition;
import com.ruoyi.ams.service.*;
import com.ruoyi.common.core.domain.AsmsAssetFullInfo;

import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AmsAssetType;
import com.ruoyi.common.core.domain.model.AmsOwnAddress;
import com.ruoyi.common.core.domain.model.AmsOwnAsset;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.core.domain.KeyValueVo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.security.annotation.PreAuthorize;
import com.ruoyi.system.controller.SysDeptController;
import com.ruoyi.system.controller.SysUserController;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.asms.service.IAsmsAssetFullInfoService;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * 资产领用退库Controller
 * 
 * @author yfkj
 * @date 2022-05-16
 */
@RestController
@RequestMapping("/ams/requisition")
public class AmsAssetRequisitionController extends BaseController
{
    @Autowired
    private IAmsAssetRequisitionService amsAssetRequisitionService;

    @Autowired
    private IAmsAssetTypeService amsAssetTypeService;
    @Autowired
    private IAmsOwnAddressService amsOwnAddressService;
    @Autowired
    private AmsReusingService amsReusingService;
    @Autowired
    private IAmsOwnAssetService amsOwnAssetService;
    @Autowired
    private IAsmsAssetFullInfoService asmsAssetFullInfoService;
//    @Autowired
//    private RemoteUserService remoteUserService;
//    @Autowired
//    private RemoteDeptService remoteDeptService;
    @Autowired
    private SysUserController userController;
    @Autowired
    private SysDeptController deptController;
    /**
     * 查询资产领用列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:requisition:list")
    @ApiOperation(value = "获取资产领用列表", response = AmsAssetRequisition.class)
    @GetMapping("/getAmsAssetRequisitionList")
    public TableDataInfo getAmsAssetRequisitionList(@RequestParam(value = "requisitionStatus", required = false) String requisitionStatus,
                                                    @RequestParam(value = "code", required = false) String code,
                                                    @RequestParam(value = "sn", required = false) String sn,
                                                    @RequestParam(value = "assetTypeId", required = false) Long assetTypeId,
                                                    @RequestParam(value = "userId", required = false) Long userId,
                                                    @RequestParam(value = "type", required = false) Integer flag)
    {
        QueryWrapper<AmsAssetRequisition> wrapper = new QueryWrapper<>();
        if(userId!=null){
            wrapper.eq(AmsAssetRequisition.USER_ID,userId);
        }
        if(assetTypeId!=null){
            wrapper.eq(AmsAssetRequisition.ASSET_TYPE_ID,assetTypeId);
        }
        if(!StrUtil.isEmptyIfStr(sn)){
            wrapper.eq(AmsAssetRequisition.SN,sn);
        }
        if (requisitionStatus != null) {
            wrapper.eq(AmsAssetRequisition.REQUISITION_STATUS, requisitionStatus);
        }
        if (code != null) {
            AsmsAssetFullInfo assetFullInfo = asmsAssetFullInfoService
                    .getOne(new QueryWrapper<AsmsAssetFullInfo>()
                            .eq(AsmsAssetFullInfo.ASSET_CODE, code)
                            .or().eq(AsmsAssetFullInfo.SN, code), false);
            if (assetFullInfo != null) {
                wrapper.eq(AmsAssetRequisition.ASSET_ID, assetFullInfo.getAssetId());
            }
        }
        if (flag != null && flag == 1) {
            wrapper.isNotNull(AmsAssetRequisition.ACTUAL_RETURN_TIME);
        }
        wrapper.orderByDesc(AmsAssetRequisition.REQUISITION_ID);
        startPage();
        List<AmsAssetRequisition> list = amsAssetRequisitionService.list(wrapper);

        CompletableFuture<R<Map<Long, SysUser>>> future1 = CompletableFuture.supplyAsync(() ->
                userController.getAllUsers());

        CompletableFuture<R<Map<Long, SysDept>>> future2 = CompletableFuture.supplyAsync(() ->
                deptController.getAllDeptsMap());

        CompletableFuture<List<AmsAssetType>> future3 = CompletableFuture.supplyAsync(() ->
                amsAssetTypeService.list(new QueryWrapper<AmsAssetType>()
                .select(AmsAssetType.ASSET_TYPE_ID, AmsAssetType.ASSET_TYPE_NAME)));

        CompletableFuture<List<AsmsAssetFullInfo>> future4 = CompletableFuture.supplyAsync(() ->
                asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .select(AsmsAssetFullInfo.ASSET_ID, AsmsAssetFullInfo.ASSET_CODE)));

        CompletableFuture<List<AmsOwnAddress>> future5 = CompletableFuture.supplyAsync(() ->
                amsOwnAddressService.list(new QueryWrapper<AmsOwnAddress>()
                .select(AmsOwnAddress.ADDRESS_ID, AmsOwnAddress.FULL_NAME)));

        HashMap<Long, String> typeMap = new HashMap<>();
        HashMap<Long, String> assetInfoMap = new HashMap<>();
        HashMap<Long, String> addressMap = new HashMap<>();
        R<Map<Long, SysUser>> allUsers = new R<>();
        R<Map<Long, SysDept>> allDeptsMap = new R<>();
        List<AmsAssetType> types = new ArrayList<>();
        List<AsmsAssetFullInfo> fullInfos = new ArrayList<>();
        List<AmsOwnAddress> addresses = new ArrayList<>();
        try {
            allUsers = future1.get();
            if (allUsers.getCode() == R.FAIL) {
                return amsReusingService.resovleError();
            }
            allDeptsMap = future2.get();
            if (allDeptsMap.getCode() == R.FAIL) {
                return amsReusingService.resovleError();
            }
            types = future3.get();
            fullInfos = future4.get();
            addresses = future5.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        for (AmsAssetType type : types) {
            typeMap.put(type.getAssetTypeId(), type.getAssetTypeName());
        }

        for (AsmsAssetFullInfo fullInfo : fullInfos) {
            assetInfoMap.put(fullInfo.getAssetId(), fullInfo.getAssetCode());
        }

        for (AmsOwnAddress address : addresses) {
            addressMap.put(address.getAddressId(), address.getFullName());
        }

        Map<Long, SysUser> userMap = allUsers.getData();
        Map<Long, SysDept> deptMap = allDeptsMap.getData();
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy.MM.dd");

        for (AmsAssetRequisition requisition : list) {
            if (requisition.getUserId() != null) {
                SysUser sysUser = userMap.get(requisition.getUserId());
                if (sysUser != null) {
                    requisition.setUserName(sysUser.getNickName());
                }
            }
            if (requisition.getDeptId() != null) {
                SysDept sysDept = deptMap.get(requisition.getDeptId());
                if (sysDept != null) {
                    requisition.setDeptName(sysDept.getDeptFullName());
                }
            }
            if (requisition.getAssetTypeId() != null) {
                requisition.setAssetTypeName(typeMap.get(requisition.getAssetTypeId()));
            }
            if (requisition.getAssetId() != null) {
                requisition.setAssetCode(assetInfoMap.get(requisition.getAssetId()));
            }
            if (requisition.getAddressId() != null) {
                requisition.setAddressName(addressMap.get(requisition.getAddressId()));
            }
            if (requisition.getChargerId() != null) {
                SysUser sysUser = userMap.get(requisition.getChargerId());
                if (sysUser != null) {
                    requisition.setChargerName(sysUser.getNickName());
                }
            }
            if (requisition.getReturnChargerId() != null) {
                SysUser sysUser = userMap.get(requisition.getReturnChargerId());
                if (sysUser != null) {
                    requisition.setReturnChargerName(sysUser.getNickName());
                }
            }
            if (requisition.getReturnAddressId() != null) {
                requisition.setReturnAddressName(addressMap.get(requisition.getReturnAddressId()));
            }
            if (requisition.getRequisitionTime() != null) {
                requisition.setRequisitionTimeStr(fmt.format(new Date(requisition.getRequisitionTime())));
            }
            if (requisition.getExpectReturnTime() != null) {
                requisition.setExpectReturnTimeStr(fmt.format(new Date(requisition.getExpectReturnTime())));
            }
            if (requisition.getActualReturnTime() != null) {
                requisition.setActualReturnTimeStr(fmt.format(new Date(requisition.getActualReturnTime())));
            }
            if (requisition.getCreateTime() != null) {
                requisition.setCreateTimeStr(fmt.format(new Date(requisition.getCreateTime())));
            }
            if (requisition.getUpdateTime() != null) {
                requisition.setUpdateTimeStr(fmt.format(new Date(requisition.getUpdateTime())));
            }
        }
        return getDataTable(list, 10);
    }


    /**
     * 获取资产领用退库详细信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:requisition:query")
    //@ApiOperation(value = "获取资产领用退库详情")
    @GetMapping(value = "/getAmsAssetRequisitionById")
    public AjaxResult getAmsAssetRequisitionById(@RequestParam("requisitionId") Long requisitionId)
    {
        return AjaxResult.success(amsAssetRequisitionService.selectAmsAssetRequisitionByRequisitionId(requisitionId));
    }

    /**
     * 新增资产领用退库
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:requisition:add")
    @Log(title = "资产领用", businessType = BusinessType.INSERT)
    @ApiOperation(value = "新增资产领用")
    @PostMapping(value = "/addAmsAssetRequisition")
    public AjaxResult addAmsAssetRequisition(@RequestBody AmsAssetRequisition amsAssetRequisition)
    {
        if (amsAssetRequisition.getAssetIds().length == 0) {
            return AjaxResult.error("请至少选择一个资产");
        }
        HashMap<Long, Long> assetIdTypeIdMap = amsReusingService.getAssetIdTypeIdMap();
        List<AmsAssetRequisition> requisitions = new ArrayList<>();
        for (Long assetId : amsAssetRequisition.getAssetIds()) {

            AmsAssetRequisition requisition = new AmsAssetRequisition();
            BeanUtils.copyProperties(amsAssetRequisition, requisition);
            requisition.setSn(amsReusingService.createSn());
            requisition.setCreateTime(System.currentTimeMillis());
            requisition.setAssetId(assetId);
            requisition.setChargerId(SecurityUtils.getUserId());
            requisition.setAssetTypeId(assetIdTypeIdMap.get(assetId));
            requisitions.add(requisition);
        }
        amsOwnAssetService.update(new UpdateWrapper<AmsOwnAsset>().set(AmsOwnAsset.ASSET_STATUS,1).in(AmsOwnAsset.ASSET_ID,amsAssetRequisition.getAssetIds()));
        asmsAssetFullInfoService.update(new UpdateWrapper<AsmsAssetFullInfo>().set(AsmsAssetFullInfo.ASSET_STATUS,1).in(AsmsAssetFullInfo.ASSET_ID,amsAssetRequisition.getAssetIds()));
        amsAssetRequisitionService.saveBatch(requisitions);
        return AjaxResult.success();
    }
    @PreAuthorize
    @ApiOperation(value = "新增资产退库")
    @PostMapping(value = "/backAmsAssetRequisitionList")
    public AjaxResult backAmsAssetRequisitionList(@RequestBody List<AmsAssetRequisition> requisitions)
    {

        Set<Long> assetIds = requisitions.stream().map(AmsAssetRequisition::getAssetId).collect(Collectors.toSet());

        amsOwnAssetService.update(new UpdateWrapper<AmsOwnAsset>().set(AmsOwnAsset.ASSET_STATUS,2).in(AmsOwnAsset.ASSET_ID,assetIds));
        asmsAssetFullInfoService.update(new UpdateWrapper<AsmsAssetFullInfo>().set(AsmsAssetFullInfo.ASSET_STATUS,2).in(AsmsAssetFullInfo.ASSET_ID,assetIds));
        amsAssetRequisitionService.updateBatchById(requisitions);

        return AjaxResult.success();
    }
    /**
     * 修改资产领用退库
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:requisition:edit")
    @Log(title = "资产领用退库", businessType = BusinessType.UPDATE)
    //@ApiOperation(value = "修改资产领用退库")
    @PostMapping(value = "/editAmsAssetRequisition")
    public AjaxResult editAmsAssetRequisition(@RequestBody AmsAssetRequisition amsAssetRequisition)
    {
        if (amsAssetRequisition.getAssetIds().length == 0) {
            return AjaxResult.error("请至少选择一个资产");
        }
        List<AmsAssetRequisition> requisitions = new ArrayList<>();
        for (Long assetId : amsAssetRequisition.getAssetIds()) {
            AmsAssetRequisition requisition = new AmsAssetRequisition();
            BeanUtils.copyProperties(amsAssetRequisition, requisition);
            requisition.setAssetId(assetId);
            requisition.setUpdateTime(System.currentTimeMillis());
            requisitions.add(requisition);
        }
        amsAssetRequisitionService.updateBatchById(requisitions);
        return AjaxResult.success();
    }

    /**
     * 删除资产领用退库
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:requisition:remove")
    @Log(title = "资产领用退库", businessType = BusinessType.DELETE)
	@GetMapping("/removeAmsAssetRequisitions")
    public AjaxResult removeAmsAssetRequisitions(@RequestParam Long[] requisitionIds)
    {
        return toAjax(amsAssetRequisitionService.deleteAmsAssetRequisitionByRequisitionIds(requisitionIds));
    }
    @GetMapping("/getAmsAssetRequisitionNamesForSelect")
    //@ApiOperation(value = "获取资产领用退库名称列表用于下拉搜索")
    public AjaxResult getAmsAssetRequisitionNamesForSelect()
    {
        List<AmsAssetRequisition> list = amsAssetRequisitionService.list();//自行加条件
        List<KeyValueVo> resultList = new ArrayList<>();
        for (AmsAssetRequisition amsAssetRequisition: list ) {
            KeyValueVo vo = new KeyValueVo();
            //vo.setKey(it.getId());
            //vo.setValue(it.getName());
            resultList.add(vo);
        }


        return AjaxResult.success(resultList);
    }
    /**
     * 导出资产领用退库列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:requisition:export")
    @Log(title = "资产领用退库", businessType = BusinessType.EXPORT)
    @PostMapping("/exportAmsAssetRequisition")
    public String exportAmsAssetRequisition(HttpServletResponse response, AmsAssetRequisition amsAssetRequisition) throws IOException
    {
        List<AmsAssetRequisition> list = amsAssetRequisitionService.selectAmsAssetRequisitionList(amsAssetRequisition);
        ExcelUtil<AmsAssetRequisition> util = new ExcelUtil<AmsAssetRequisition>(AmsAssetRequisition.class);
        util.exportExcel(response, list, "资产领用退库数据");
        return "";
    }

}
